from sqlite3 import IntegrityError

from flask import Flask, Blueprint, jsonify, request, session
from werkzeug.security import generate_password_hash, check_password_hash
from flask_jwt_extended import create_access_token, create_refresh_token, get_jwt_identity, get_jwt, jwt_required

from applications.models.backend import *  # 导入后台管理员模型
from .tags import register_tags_bps  # 导入标签蓝图注册函数
from .user import register_user_bps  # 导入用户管理蓝图注册函数
from .admin import register_admin_bps  # 导入管理员管理蓝图注册函数
from .role import register_role_bps  # 导入角色管理蓝图注册函数
from .auth import register_auth_bps, generate_jwt, decode_jwt  # 导入认证管理蓝图注册函数
from .order import register_order_bp  # 导入订单管理蓝图注册函数
from .article import register_article_bps  # 导入故事文章管理蓝图注册函数
from .goods import register_goods_bps  # 导入商品管理蓝图注册函数
from .category import register_category_bps # 导入商品分类蓝图
from .permission import register_permission_bps  # 导入权限管理蓝图注册函数
from .comment import register_comment_bps  # 导入评论管理蓝图注册函数
from .statistics import register_statistics_bps  # 导入统计管理蓝图注册函数

# 创建后台系统,url_prefix='/system',前缀路由/system
system_bp = Blueprint('system', __name__, url_prefix='/system')


@system_bp.before_request
def before_request():
    print('Session before request:', session)


# 管理端用户登录
@system_bp.route('/login', methods=['POST'])
def login_admin():
    data = request.get_json()
    if not data or 'username' not in data or 'password' not in data:
        return jsonify({'message': '用户名和密码是必填项'}), 400

    username = data['username']
    password = data['password']
    userAdmin = Admin.query.filter_by(username=username).first()

    # if userAdmin and check_password_hash(userAdmin.password, password):  # 使用 check_password_hash 验证密码
    if not userAdmin:
        return jsonify({'code': 403, 'msg': '账号不存在，请注册！'})
    print(userAdmin.password, password)
    print(check_password_hash(userAdmin.password, password))
    if userAdmin and check_password_hash(userAdmin.password, password):  # 使用 check_password_hash 验证密码
    # if userAdmin and userAdmin.password:  # 使用 check_password_hash 验证密码
        # 验证通过，创建 access token 和 refresh token
        # identity 参数用来标识用户，我们这里存入用户的ID
        access_token = create_access_token(identity=str(userAdmin.id))
        refresh_token = create_refresh_token(identity=str(userAdmin.id))

        # 更新最后登录时间和IP
        userAdmin.last_login_at = datetime.now(UTC)
        userAdmin.last_login_ip = request.remote_addr
        db.session.commit()

        return jsonify({
            'code': 200,
            'msg': '登录成功！',
            'accessToken': access_token,
            'refreshToken': refresh_token
        })

    return jsonify({'code': 401, 'msg': '用户名或密码错误', 'message': '用户名或密码错误'})


# 注册管理端用户
@system_bp.route('/register-admin', methods=['POST'])
def register_admin():
    data = request.json  # 获取请求中的JSON数据
    username = data.get('username')  # 获取用户名
    password = data.get('password')  # 获取密码
    phone = data.get('phone')  # 获取手机号
    # 检查请求参数是否为空
    if not username or not password or not phone:
        return jsonify({'code': 400, 'msg': '用户名、密码和手机号不能为空！', 'message': '用户名、密码和手机号不能为空！'}) # 返回错误信息
    # 检查管理员是否已存在，以及手机号是否已被注册
    existing_admin = Admin.query.filter_by(username=username).first()
    existing_phone = Admin.query.filter_by(phone=phone).first()

    if existing_admin:
        return jsonify({'code': 400, 'msg': '用户名已存在！', 'message': '用户已存在！'})  # 返回错误信息
    if existing_phone:
        return jsonify({'code': 400, 'msg': '手机号已被注册！', 'message': '手机号已被注册！'})

    hashed_password = generate_password_hash(password)  # 使用 generate_password_hash 加密密码
    # 创建新管理员
    new_admin = Admin(username=username, password=hashed_password, phone=phone)
    db.session.add(new_admin)  # 将新管理员添加到数据库会话
    db.session.commit()  # 提交会话

    return jsonify({'code': 200, 'msg': '管理员注册成功！'}) # 返回成功信息


# 获取管理端用户信息
@system_bp.route('/user/info', methods=['GET'])
@jwt_required()  # 保护此路由，必须提供 access token
def get_user_info():
    try:
        current_user_id = int(get_jwt_identity())  # 从 token 中获取用户 ID
        admin = Admin.query.get(current_user_id)
        if not admin:
            return jsonify({"message": "用户不存在"}), 404
        # 序列化管理员对象为字典，排除密码字段
        admin_info = {
            'id': admin.id,
            'username': admin.username,
            'nickname': admin.nickname,
            'email': admin.email,
            'sex': admin.sex,
            'avatar': admin.avatar,
            'real_name': admin.real_name,
            'birthday': admin.birthday.strftime('%Y-%m-%d') if admin.birthday else None,
            'phone': admin.phone,
            'headimgurl': 'https://tse4-mm.cn.bing.net/th/id/OIP-C.MqovI15z6O3xqrbcjHUm4gAAAA?r=0&o=7rm=3&rs=1&pid=ImgDetMain',
            'description': admin.introduction,
            'address': admin.address,
            'roles': [role.code for role in admin.roles],  # 附加角色信息
            'permissions': list(set(perm.code for role in admin.roles for perm in role.permissions)),  # 附加权限信息
            'created_at': admin.created_at.strftime('%Y-%m-%d %H:%M:%S')
        }
        return jsonify({'code': 200, 'data': admin_info, 'success': True, })
    except Exception as e:
        # 统一 422，返回详细字段错误
        return jsonify({"code": 422, "message": str(e)})

# 获取路由
@system_bp.route('/get-async-routes', methods=['GET'])
def get_async_routes():
    return jsonify({
        'code': 200,
        'success': 'true',
        'data': [
            {
                "path": "/system",
                "meta": {
                    "icon": "ri:settings-3-line",
                    "title": "menus.pureSysManagement",
                    "rank": 14
                },
                "children": [
                    {
                        "path": "/system/user/index",
                        "name": "SystemUser",
                        "meta": {
                            "icon": "ri:admin-line",
                            "title": "menus.pureUser",
                            "roles": ["admin"]
                        }
                    },
                    {
                        "path": "/system/client-user/index",
                        "name": "ClientUser",
                        "meta": {
                            "icon": "ri:user-line",
                            "title": "menus.clientUser",
                            "roles": ["admin"]
                        }
                    },
                    {
                        "path": "/system/role/index",
                        "name": "SystemRole",
                        "meta": {
                            "icon": "ri:admin-fill",
                            "title": "menus.pureRole",
                            "roles": ["admin"]
                        }
                    }
                ]
            }
        ]
    })

# 修改管理端用户信息
@system_bp.route('/updateInfo', methods=['PUT'])
@jwt_required()
def update_admin():
    data = request.json
    current_user_id = get_jwt_identity()
    admin = Admin.query.get(current_user_id)  # 直接主键查，更简洁
    if not admin:
        return jsonify(msg='用户不存在'), 404

    # 1. 生日字段（前端传 ISO-8601 带 Z）
    birthday_str = data.get('birthday')
    if birthday_str:
        try:
            admin.birthday = datetime.fromisoformat(birthday_str.replace('Z', '+00:00'))
        except ValueError:
            return jsonify(msg='生日格式错误'), 400

    # 2. 性别字段（防脏数据）
    sex_raw = data.get('sex')
    print('性别字段处理完毕0', sex_raw)
    if sex_raw == '' or sex_raw is None:
        admin.sex = 0  # 业务默认：0-未知
        print('性别字段处理完毕1', admin.sex)
    else:
        if sex_raw not in ('0', '1', 0, 1):
            return jsonify(msg='性别值只能是 0 或 1'), 400
        admin.sex = int(sex_raw)
    print('性别字段处理完毕2', admin.sex)
    print('即将提交 admin.id=', admin.id, 'admin.sex=', admin.sex)
    # 3. 普通文本字段长度/空串统一处理
    admin.username = (data.get('username') or '').strip() or admin.username
    admin.nickname = (data.get('nickname') or '').strip() or admin.nickname
    admin.email = (data.get('email') or '').strip() or admin.email
    admin.real_name = (data.get('real_name') or '').strip() or admin.real_name
    admin.phone = (data.get('phone') or '').strip() or admin.phone
    admin.introduction = (data.get('introduction') or '').strip() or admin.introduction
    admin.address = (data.get('address') or '').strip() or admin.address
    admin.avatar = data.get('avatar') or admin.avatar

    # 4. 一次提交
    try:
        db.session.commit()
    except IntegrityError as e:
        db.session.rollback()
        return jsonify(msg='字段重复或冲突'), 409

    return jsonify({
        'code': 200,
        'success': 'true',
        'data': {
            'id': admin.id,
            'username': admin.username,
            'nickname': admin.nickname,
            'email': admin.email,
            'sex': admin.sex,
            'avatar': admin.avatar,
            'real_name': admin.real_name,
            'birthday': admin.birthday.strftime('%Y-%m-%d') if admin.birthday else None,
            'phone': admin.phone,
            'roles': [role.code for role in admin.roles],
            'permissions': list(set(perm.code for role in admin.roles for perm in role.permissions)),
        },
        'msg': '更新成功'
    }), 200

# 账户设置-重置密码
@system_bp.route('/users/<int:user_id>/reset-password', methods=['POST'])
def reset_user_password(user_id):
    """重置用户密码"""
    user = Admin.query.get(user_id)
    if not user:
        return jsonify({'code': 404, 'message': '未找到用户'}), 404

    data = request.get_json()

    old_pwd = data.get('oldPassword')
    new_pwd = data.get('newPassword')

    if not old_pwd or not new_pwd:
        return jsonify(code=400, message='旧密码与新密码必填')

    if not check_password_hash(user.password, old_pwd):
        return jsonify(code=403, message='旧密码错误')

    user.password = generate_password_hash(new_pwd)
    db.session.commit()

    return jsonify({'code': 200, 'message': '密码重置成功！'})
# 账户设置-个人安全日志
@system_bp.route('/mine-logs', methods=['GET'])
@jwt_required()
def mine_logs():
    list = [
        {
            'id': 1,
            'ip': '127.1.0.1',
            'address': "中国河南省信阳市",
            'system': "macOS",
            'browser': "Chrome",
            'summary': "账户登录",
            'operatingTime': "2025-08-01 16:00:00"

        },
        {
            'id': 2,
            'ip': '127.1.0.1',
            'address': "中国河南省信阳市",
            'system': "macOS",
            'browser': "Chrome",
            'summary': "账户登出",
            'operatingTime': "2025-08-01 16:00:00"

        }
    ]
    return jsonify({
        'code': 200,
        'data': list,
        'success': True,
        'total': len(list)
    })


# 管理端用户登出
blacklist = set()  # 使用集合存储黑名单


@system_bp.route('/logout', methods=['POST'])
@jwt_required()  # 需要有效的 access token 才能登出
def logout_admin():
    token = request.headers.get('Token') or get_jwt()
    if token:
        blacklist.add(token)  # 将 token 添加到黑名单
        return jsonify({'code': 200, 'msg': '退出成功！'}), 200
    return jsonify({'code': 403, 'msg': '退出失败！'})


# 刷新 Access Token
@system_bp.route('/refresh-token', methods=['POST'])
@jwt_required(refresh=True)  # 注意这里需要传入 refresh=True，表示只接受 refresh token
def refresh():
    current_user_id = get_jwt_identity()
    new_access_token = create_access_token(identity=current_user_id)
    expires = "2030/10/30 23:59:59"
    return jsonify(access_token=new_access_token, expires=expires)


def register_system_bps(app: Flask):
    # 在admin_bp主蓝图下注册子主蓝图
    app.register_blueprint(system_bp)
    # 注册子蓝图
    register_user_bps(app)
    register_admin_bps(app)
    register_role_bps(app)
    register_tags_bps(app)
    register_order_bp(app)
    register_article_bps(app)
    register_goods_bps(app)
    register_category_bps(app)
    register_comment_bps(app)
    register_statistics_bps(app)
    register_permission_bps(app)  # 注册权限管理蓝图
    register_auth_bps(app)  # 注册认证管理蓝图
